package lList;

public class LinkedList<T> {
	
	class Node {

//		public int index;
		public T data;
		public Node next;
		public Node previous;
	}


	private Node start;
	private Node end;
	private int elements;
	
	
//	private abstract void f();
	
	public LinkedList () {
		start = null;
		end = null;
		elements = 0;
	}
	
	public void add(T element) {
		if (element == null)
			throw new NullPointerException();
		
//		Node<T> temp = start;
//
//		if(start == null) {
//			start = new Node<T>();
//			start.data = element;
//		}
//		else {
////			Node<T> connectPrevious = temp;
//			while (temp.next != null) {
//				temp = temp.next;
////				if(temp.next != null) {
////					connectPrevious = connectPrevious.next;
////				}
//			}
//
//			Node<T> current = new Node<T>();
//			current.data = element;
//			current.next = null;
////			current.previous = connectPrevious;
////			current.index = elements++;
//			elements++;
//
//			temp.next = current;
//			current.previous = temp;
//		}
		
		if(end == null) {
			start = new Node();
			start.data = element;
			end = start;
		}
		else {
			Node current = new Node();
			current.data = element;
			current.next = null;
			current.previous = end;
			elements++;

			end.next = current;
		}
	}
	
	public void remove(int index) {
		if (index >= elements) {
			throw new NullPointerException();
		}
	
		if(start != null) {
			Node temp;
			if(index < elements / 2)
				temp = start;
			else
				temp = end;
			
			
			for (int i = 0; i < index; i++) {
				temp = temp.next;
			}
			
			Node temp2 = temp.previous;

			Node temp3= temp.next;

			temp2.next = temp3;
			temp3.previous = temp2;
			temp = null;

			this.elements--;
		}

	}
	
	public T get(int index) {
		if (index >= elements) {
			throw new NullPointerException();
		}
		
		Node temp;

		if (index < elements / 2) {
			temp = start;
			
			for (int i = 0; i < index; i++) {
				temp = temp.next;
			}
		}
		else {
			temp = end;
			
			for (int i = elements; i < index; i++) {
				temp = temp.next;
			}
		}


		return temp.data;

	}
	
	public void insertAt(int insertIndex, T element) {
		if (insertIndex >= elements || element == null)
			throw new NullPointerException();

		Node temp = start;

		for (int i = 0; i < insertIndex; i++) {
			temp = temp.next;
		}

		Node newNode = new Node();
		newNode.data = element;
		newNode.next = temp.next;
//		newNode.index = insertIndex;

		temp.next = newNode;
		this.elements++;

//		while (newNode.next != null) {
//			newNode = newNode.next;
////			newNode.index++;
//		}
		
	}
	
	
	
}
